home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / telecomm / sticpsrc.lzh / SOURCE.ARC / DIRUTIL.C < prev    next >
C/C++ Source or Header  |  1990-05-04  |  26KB  |  1,157 lines

  1. /* dirutil.c - MS-DOS directory reading routines
  2.  *
  3.  * Bdale Garbee, N3EUA, Dave Trulli, NN2Z, and Phil Karn, KA9Q
  4.  * Directory sorting by Mike Chepponis, K3MC
  5.  * adapted for ATARI ST & cleaned up by Rob Janssen, PE1CHL
  6.  * added more shell commands by PE1CHL
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <ctype.h>
  11.  
  12. #ifdef MSDOS
  13. # define IS_ERROR(x)    (x) == -1    /* error return from MSDOS */
  14. # ifdef    MSC
  15. #  include <sys/types.h>
  16. #  include <sys/stat.h>
  17. #  define ST_HIDDEN    _A_HIDDEN    /* hidden from search */
  18. #  define ST_DIRECT    _A_SUBDIR    /* directory */
  19. # else
  20. #  ifdef __TURBOC__
  21. #   define ST_HIDDEN    FA_HIDDEN    /* Hidden from search */
  22. #   define ST_DIRECT    FA_DIREC    /* Directory */
  23. #  else    /* AZTEC */
  24. #   include <stat.h>
  25. #   define st_mode    st_attr        /* what's in a name? */
  26. #  endif
  27. # endif
  28. #endif
  29.  
  30. #ifdef ATARI_ST
  31. # ifdef MWC
  32. #  include <stat.h>
  33. #  include <osbind.h>
  34. #  define bdos        gemdos        /* Atari OS call */
  35. #  define dos(a,b,c,d,e,f) gemdos(a,d,c) /* only valid for FIND func */
  36. #  define ST_HIDDEN    S_IJHID        /* Hidden from search */
  37. #  define ST_DIRECT    S_IJDIR        /* Directory */
  38. # endif
  39. # ifdef __TURBOC__
  40. #  include <tos.h>
  41. #  include <ext.h>
  42. #  define ST_HIDDEN    FA_HIDDEN    /* Hidden from search */
  43. #  define ST_DIRECT    FA_DIREC    /* Directory */
  44. # endif
  45. # define IS_ERROR(x)    (x) < 0        /* error return from gemdos */
  46. #endif
  47.  
  48. #include "global.h"
  49.  
  50. #define SET_DTA        0x1a
  51. #define FIND_FIRST    0x4e
  52. #define FIND_NEXT    0x4f
  53.  
  54. struct dirent {
  55.     char rsvd[21];
  56.     char attr;
  57.     short ftime;
  58.     short fdate;
  59.     long fsize;
  60.     char fname[13];
  61. };
  62. #define NULLENT (struct dirent *)0
  63.  
  64. struct dirsort {
  65.     struct dirsort *prev;
  66.     struct dirsort *next;
  67.     struct dirent *direntry;
  68. };
  69. #define NULLSORT (struct dirsort *)0
  70.  
  71. #ifdef ATARI_ST
  72. static char *buffer;            /* buffer for filecopy */
  73. static int  bufsiz;            /* size of buffer */
  74. #endif
  75.  
  76. static char nofile[] = "No file \"%s\"\n";
  77. extern char cantopen[];
  78.  
  79. static int cpfile(),cptodir(),filedelete(),dirremove(),
  80.        wildcard(),getarcdir();
  81. static void dir_sort(),format_dir(),format_fname(),diskfree(),free_clist();
  82. static void commas();
  83. int iswild(),isdir();
  84. char *basename();
  85.  
  86. /* Change working directory */
  87. docd(argc,argv)
  88. int argc;
  89. char *argv[];
  90. {
  91.     char dirname[128];
  92. #ifdef MSDOS
  93.     char *getcwd();
  94. #endif
  95.  
  96.     if(argc > 1){
  97.         if(IS_ERROR(chdir(argv[1]))){
  98.             printf("Can't change directory\n");
  99.             return 1;
  100.         }
  101.     }
  102.  
  103. #ifdef MSDOS
  104. # if (defined(MSC) || defined(__TURBOC__))
  105.     if(getcwd(dirname,sizeof(dirname)-1) != NULLCHAR){
  106. # else
  107.     dirname[0] = '\\';
  108.     if(getcwd(dirname + 1,sizeof(dirname)-2) != NULLCHAR){
  109. # endif
  110. #endif
  111. #ifdef ATARI_ST
  112.     dirname[0] = Dgetdrv() + 'A';
  113.     dirname[1] = ':';
  114.     if(Dgetpath(dirname + 2,0) == 0){
  115.         if(dirname[2] == '\0'){
  116.             dirname[2] = '\\';
  117.             dirname[3] = '\0';
  118.         }
  119. #endif
  120.         cleanup_fname(dirname);
  121.         printf("%s\n",dirname);
  122.     }
  123.     return 0;
  124. }
  125.  
  126. /* copy files */
  127. docopy(argc,argv)
  128. int argc;
  129. char *argv[];
  130. {
  131.     int stat;
  132.     int i;
  133. #ifdef ATARI_ST
  134.     long maxbuf;
  135. #endif
  136.  
  137.     for (i = 1; i < argc; i++)
  138.     cleanup_fname(argv[i]);
  139.  
  140.     if (iswild(argv[argc - 1])){
  141.     printf("Last arg cannot be wildcard\n");
  142.     return 1;
  143.     }
  144.  
  145. #ifdef ATARI_ST
  146.     /* On Atari ST, use a big buffer allocated from GEMDOS */
  147.  
  148.     if ((maxbuf = (long) Malloc(-1L)) < 512L)    /* ask maximum buffer size */
  149.     {
  150.     printf("Cannot allocate buffer\n");
  151.     return(1);
  152.     }
  153.  
  154.     bufsiz = maxbuf & 32767;        /* limit bufsize to safe value */
  155.     bufsiz &= ~512L;            /* round down to 512-byte multiple */
  156.  
  157.     if ((long) (buffer = (char *) Malloc((long) bufsiz)) < 0) {
  158.     printf("GEMDOS error during buffer allocation\n");
  159.     return(1);
  160.     }
  161. #endif
  162.  
  163.     if (!isdir(argv[argc - 1]))        /* check type of destination */
  164.     {
  165.     if (argc == 3 && !iswild(argv[1])){ /* file-to-file copy */
  166.         stat = cpfile(argv[1],argv[2]);
  167.     } else {
  168.         printf("Last arg must be a directory\n");
  169.         stat = 1;
  170.     }
  171.     } else {
  172.     stat = wildcard(argc - 1,argv,cptodir,argv[argc - 1]);
  173.     }
  174.  
  175. #ifdef ATARI_ST
  176.     Mfree(buffer);            /* free the buffer */
  177. #endif
  178.  
  179.     return(stat);
  180. }
  181.  
  182. /* delete files */
  183. dodelete(argc,argv)
  184. int argc;
  185. char *argv[];
  186. {
  187.     return wildcard(argc,argv,filedelete,NULL);
  188. }
  189.  
  190. /* List directory to console. [-/]w option selects "wide" format */
  191. dodir(argc,argv)
  192. int argc;
  193. char *argv[];
  194. {
  195.     char *path;
  196.     int full = 1;
  197.  
  198.     if (argc > 1 &&
  199.     (argv[1][0] == '-' || argv[1][0] == '/') && argv[1][1] == 'w') {
  200.     full = -1;
  201.     argv++;
  202.     argc--;
  203.     }
  204.  
  205.     if(argc >= 2){
  206.     path = argv[1];
  207.     } else {
  208.     path = "*.*";
  209.     }
  210.     getdir(path,full,0,stdout);
  211.     return 0;
  212. }
  213.  
  214. /* make directories */
  215. domkdir(argc,argv)
  216. int argc;
  217. char *argv[];
  218. {
  219.     int i;
  220.     int st = 0;
  221.     char force = 0;
  222.  
  223.     for (i = 1; i < argc; i++){
  224.     if (!strcmp(argv[i],"-f")){        /* -f flag = force */
  225.         force = 1;
  226.         continue;
  227.     }
  228.  
  229.     cleanup_fname(argv[i]);
  230.  
  231.     if (iswild(argv[i]) ||(mkdir(argv[i]) && !force)){
  232.         printf("Cannot make directory \"%s\"\n",argv[i]);
  233.         st = 1;
  234.     }
  235.     }
  236.  
  237.     return st;
  238. }
  239.  
  240. /* rename a file */
  241. dorename(argc,argv)
  242. int argc;
  243. char *argv[];
  244. {
  245.     cleanup_fname(argv[1]);
  246.     cleanup_fname(argv[2]);
  247.  
  248.     if (iswild(argv[1]) || iswild(argv[2])){
  249.     printf("No wildcard file rename\n");
  250.     return 1;
  251.     }
  252.  
  253.     if (rename(argv[1],argv[2])){
  254.     printf("Cannot rename \"%s\" to \"%s\"\n",argv[1],argv[2]);
  255.     return 1;
  256.     }
  257.     return 0;
  258. }
  259.  
  260. /* remove directories */
  261. dormdir(argc,argv)
  262. int argc;
  263. char *argv[];
  264. {
  265.     return wildcard(argc,argv,dirremove,NULL);
  266. }
  267.  
  268. /* type a file on the console */
  269. /* number of lines can be given as second parameter, negative value */
  270. /* will be taken as tail lines. */
  271.  
  272. dotype(argc,argv)
  273. int argc;
  274. char *argv[];
  275. {
  276.     FILE *fp;
  277.     int c;
  278.     int lines = 0;
  279.  
  280.     cleanup_fname(argv[1]);
  281.  
  282.     if (iswild(argv[1])){
  283.     printf("No wildcard file type\n");
  284.     return 1;
  285.     }
  286.  
  287.     if (argc > 2)
  288.     if ((lines = atoi(argv[2])) == 0)
  289.         lines = -24;
  290.  
  291.     if ((fp = fopen(argv[1],binmode[READ_BINARY])) == NULL){
  292.     printf(cantopen,argv[1]);
  293.     return 1;
  294.     }
  295.  
  296.     if (lines < 0){            /* tail of file */
  297.     fseek(fp,0L,2);            /* seek to EOF */
  298.  
  299.     while (fseek(fp,-2L,1) != -1){    /* backup one character (+getc) */
  300.         if ((c = getc(fp)) == '\n'){
  301.         if (++lines == 0)
  302.             break;        /* done enough, start printing */
  303.  
  304. #if (defined(MSDOS) || defined(ATARI_ST))
  305.         fseek(fp,-1L,1);    /* seek past \r, too */
  306. #endif
  307.         }
  308.     }
  309.  
  310.     if (lines != 0)            /* could not find so many? */
  311.         fseek(fp,0L,0);        /* then do from start of file */
  312.     }
  313.  
  314.     while ((c = getc(fp)) != EOF){    /* type the (head of the) file */
  315. #if (defined(MSDOS) || defined(ATARI_ST))
  316.     if (c == '\r'){            /* it is a CR, probably CR/LF */
  317.         if ((c = getc(fp)) != '\n'){/* read next and verify it is LF */
  318.         ungetc(c,fp);        /* no, put it back */
  319.         c = '\r';        /* and process the CR */
  320.         }
  321.     }
  322. #endif
  323.  
  324.     if (c >= ' ' || c == '\n' || c == '\r' || c == '\b' || c == '\t')
  325.         putchar(c);
  326.     else
  327.         putchar('.');
  328.  
  329.     if (lines && c == '\n' && --lines == 0 && getc(fp) != EOF){
  330.         fclose(fp);
  331.         return 0;
  332.     }
  333.     }
  334.  
  335.     printf("EOF\n");
  336.     fclose(fp);
  337.     return 0;
  338. }
  339.  
  340. /* Create a directory listing in a temp file and return the resulting file
  341.  * descriptor. If full == 1, give a full listing; else return just a list
  342.  * of names.
  343.  */
  344. FILE *
  345. dir(path,full)
  346. char *path;
  347. int full;
  348. {
  349.     FILE *fp,*tmpfile();
  350.  
  351.     if ((fp = tmpfile()) != NULLFILE) {
  352.         getdir(path,full,0,fp);
  353.         /* This should be rewind(), but Aztec doesn't have it */
  354.         fseek(fp,0L,0);
  355.     }
  356.     return fp;
  357. }
  358.  
  359. /* wildcard filename lookup */
  360. filedir(name,times,ret_str)
  361. char *name;
  362. int times;
  363. char *ret_str;
  364. {
  365.     register char *cp,*cp1;
  366.     static struct dirent sbuf;
  367.  
  368. #ifdef    MSC
  369.     if (times == 0) {
  370.         if (_dos_findfirst(name,ST_HIDDEN|ST_DIRECT,&sbuf))
  371.             sbuf.fname[0] = '\0';
  372.     } else {
  373.         if (_dos_findnext(&sbuf))
  374.             sbuf.fname[0] = '\0';
  375.     }
  376. #else
  377. #ifdef __TURBOC__
  378.     if (times == 0) {
  379.         if (findfirst(name,&sbuf,ST_HIDDEN|ST_DIRECT))
  380.             sbuf.fname[0] = '\0';
  381.     } else {
  382.         if (findnext(&sbuf))
  383.             sbuf.fname[0] = '\0';
  384.     }
  385. #el